package antlr4.myantlrtest.test.calc;

import antlr4.myantlrtest.gen.calc.CalcBaseVisitor;
import antlr4.myantlrtest.gen.calc.CalcParser;

import java.util.HashMap;
import java.util.Map;

public class EvalVisitor extends CalcBaseVisitor<Integer> {
    /** "memory" for our calculator; variable/value pairs go here */
    Map<String, Integer> memory = new HashMap<String, Integer>();
    boolean error = false;

    /** ID '=' expr NEWLINE */
// 初始化变量的操作（赋值操作）
    @Override
    public Integer visitAssign(CalcParser.AssignContext ctx) {
        String id = ctx.ID().getText();  // id is left-hand side of '='
        int value = visit(ctx.expr());   // compute value of expression on right
        memory.put(id, value);           // store it in our memory
        return value;
    }

    /** expr NEWLINE */
// 输出表达式的计算结果
    @Override
    public Integer visitPrintExpr(CalcParser.PrintExprContext ctx) {
        Integer value = visit(ctx.expr()); // evaluate the expr child
        System.out.println(value);         // print the result
        return 0;                          // return dummy value
    }

    /** INT */
// 将字符串形式的整数转换为整数类型
    @Override
    public Integer visitInt(CalcParser.IntContext ctx) {
        return Integer.valueOf(ctx.INT().getText());
    }

    /** ID */
    @Override
    public Integer visitId(CalcParser.IdContext ctx) {
        String id = ctx.ID().getText();
// 从Map中获取变量的值 
        if ( memory.containsKey(id) ) {
            return memory.get(id);
        } else {
// 引用了不存在的变量，输出错误信息 
            System.err.println(String.format("变量<%s> 不存在！",id));
            error = true;

        }
        return 0;
    }

    /** expr op=('*'|'/') expr */
// 计算乘法和除法
    @Override
    public Integer visitMulDiv(CalcParser.MulDivContext ctx) {

        int left = visit(ctx.expr(0));  // get value of left subexpression
        int right = visit(ctx.expr(1)); // get value of right subexpression

        if ( ctx.op.getType() == CalcParser.MUL ) return left * right;
        return left / right; // must be DIV
    }

// 计算加法和减法
    /** expr op=('+'|'-') expr */
    @Override
    public Integer visitAddSub(CalcParser.AddSubContext ctx) {
        int left = visit(ctx.expr(0));  // get value of left subexpression
        int right = visit(ctx.expr(1)); // get value of right subexpression
        if ( ctx.op.getType() == CalcParser.ADD ) return left + right;
        return left - right; // must be SUB
    }

    /** '(' expr ')' */
// 处理括号表达式
    @Override
    public Integer visitParens(CalcParser.ParensContext ctx) {
        return visit(ctx.expr()); // return child expr's value
    }
}